package com.stone.framework.task.client;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.stone.framework.core.exception.BusinessException;
import com.stone.framework.message.ReqMessage;
import com.stone.framework.message.ResMessage;

import feign.hystrix.FallbackFactory;

public interface AbstractClient {

    Logger LOGGER = LoggerFactory.getLogger(AbstractClient.class);

    @RequestMapping(value = "/job/start/{jobId}", method = RequestMethod.POST)
    ResMessage<Void> start(@PathVariable("jobId") String jobId,
        @RequestBody ReqMessage<Map<String, String>> reqMessage);

    @RequestMapping(value = "/job/stop", method = RequestMethod.POST)
    ResMessage<Void> stop(@RequestBody ReqMessage<Long> reqMessage);

    @RequestMapping(value = "/job/restart", method = RequestMethod.POST)
    ResMessage<Void> restart(@RequestBody ReqMessage<Long> reqMessage);

    default void start(String jobId, String params) {
        Map<String, String> map = params == null || "".equals(params) ? new HashMap<>() : Stream.of(params.split(","))
            .collect(Collectors.toMap(param -> param.split("=")[0], param -> param.split("=")[1]));

        ResMessage<Void> resMessage = this.start(jobId, ReqMessage.build(map));
        if (!resMessage.successed()) {
            throw new BusinessException(resMessage.getHeader().getDesc());
        }
    }

    default void stop(Long executionId) {
        ResMessage<Void> resMessage = this.stop(ReqMessage.build(executionId));
        if (!resMessage.successed()) {
            throw new BusinessException(resMessage.getHeader().getDesc());
        }
    }

    default void restart(Long executionId) {
        ResMessage<Void> resMessage = this.restart(ReqMessage.build(executionId));
        if (!resMessage.successed()) {
            throw new BusinessException(resMessage.getHeader().getDesc());
        }
    }

    @Component
    public static class AbstractFallbackFactory implements FallbackFactory<AbstractClient> {

        @Override
        public AbstractClient create(Throwable cause) {
            return new AbstractClient() {

                @Override
                public ResMessage<Void> start(String jobId, ReqMessage<Map<String, String>> reqMessage) {
                    LOGGER.error("调度异常", cause);
                    return ResMessage.fail(cause.getMessage());
                }

                @Override
                public ResMessage<Void> stop(ReqMessage<Long> reqMessage) {
                    LOGGER.error("调度异常", cause);
                    return ResMessage.fail(cause.getMessage());
                }

                @Override
                public ResMessage<Void> restart(ReqMessage<Long> reqMessage) {
                    LOGGER.error("调度异常", cause);
                    return ResMessage.fail(cause.getMessage());
                }

            };
        }

    }

}
